<?php

declare(strict_types=1);

namespace App\Api\Middleware;

use App\Exception\DefaultException;
use Hyperf\Context\ApplicationContext;
use Mine\MineRequest;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

use function Hyperf\Translation\trans;

class ApiLockMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $scene = request_scene();
        $unique = api_member_id($scene);
        if (empty($unique)) {
            $unique = ApplicationContext::getContainer()->get(MineRequest::class)->ip();
        }

        $key = sprintf('api_lock:%s:%s:%d', $scene, $request->getUri()->getPath(), $unique);
        $lock = lock($key, 10);
        if (!$lock->get()) {
            throw new DefaultException(trans('message.operate_frequently'));
        }

        try {
            $response = $handler->handle($request);
        } finally {
            $lock->release();
        }

        return $response;
    }
}
